home *** CD-ROM | disk | FTP | other *** search
- #include <dos.h>
- #include <math.h>
- #include <stdio.h>
- #include <string.h>
- #include "3dtools.h"
-
- // 3dtools v0.95 - released 12-14-94
- // C++ 3d engine
- // coded by Voltaire/OTM
- // all source Copyright (C) 1994 Zach Mortensen
- //
- // compile using: wcl386 /mf /oneat /5r /d2 /c 3dtools.cpp
- //
- // NOTE: for some STRANGE reason, a GP fault appears when the /d2
- // switch is omitted, and disappears when it is used. THIS MAKES
- // DEBUGGING THE GPF VERY DIFFICULT! IT IS NOT MY FAULT! However, it
- // is VERY annoying, because the /d2 switch disables many optimizations
- // which would result in a significant speedup.
- //
- // see 3DTOOLS.NFO and OTM-94.NFO for more information
-
- world3d world;
- viewPoint camera;
- int matrix[9];
- int *perspect;
-
- //////
- //
- // dotProduct function definition
- //
- //////
-
-
- int dotProduct(point3d *p1, point3d *p2)
- {
- return((int) ((p1->rotoX * p2->rotoX) + (p1->rotoY * p2->rotoY) +
- (p1->rotoZ * p2->rotoZ)));
- }
-
- void initPerspect()
- {
- int count;
-
- perspect = new int [32768];
-
- perspect[0] = 1024 * 64;
-
- for (count = 1; count < 32768; count++)
- perspect[count] = 1024 * 64 / count;
- }
-
- void delPerspect()
- {
- delete perspect;
- }
-
- //////
- //
- // point3d class definitions
- //
- //////
-
-
- point3d::point3d()
- {
- }
-
- point3d::point3d(long x, long y, long z)
- {
- setTo(x, y, z);
- }
-
- void point3d::save(FILE *fp)
- {
- int numWritten;
-
- pointRec *temp = new pointRec;
-
- temp->localX = localX;
- temp->localY = localY;
- temp->localZ = localZ;
-
- numWritten = fwrite(temp, sizeof(pointRec), 1, fp);
-
- }
-
- void point3d::load(FILE *fp)
- {
- int numRead;
-
- pointRec *temp = new pointRec;
-
- numRead = fread(temp, sizeof(pointRec), 1, fp);
-
- localX = temp->localX;
- localY = temp->localY;
- localZ = temp->localZ;
-
- rotoX = localX;
- rotoY = localY;
- rotoZ = localZ;
- }
-
- void point3d::setTo(long x, long y, long z)
- {
- x3d = x;
- y3d = y;
- z3d = z;
-
- localX = x;
- localY = y;
- localZ = z;
-
- rotoX = x;
- rotoY = y;
- rotoZ = z;
-
- oX = 0;
- oY = 0;
- oZ = 0;
-
- xDeg = 0;
- yDeg = 0;
- zDeg = 0;
-
- // spherical schtuff
- /*
- lRho = (long) sqrt(localX * localX + localY * localY + localZ * localZ);
-
- if (localZ == 0)
- lTheta = (long) 180 * atan(localX) / PI;
- else
- lTheta = (long) 180 * atan(localX / localZ) / PI;
-
- if (lRho == 0)
- lPhi = 0;
- else
- lPhi = (long) 180 * acos(localY / lRho) / PI;
-
- gRho = lRho;
- gTheta = lTheta;
- gPhi = lPhi;
- */
- zeroNormal();
-
- xform2d();
- }
-
- // project the point to the screen
-
- void point3d::xform2d()
- {
-
- if (z3d > 0)
- {
- x2d = ((x3d << 10) / z3d) + 159;
- y2d = 99 - ((y3d << 10) / z3d);
- }
- else if (z3d == 0)
- {
- x2d = 159 + (x3d << 10);
- y2d = 99 - (y3d << 10);
- }
- else
- {
- x2d = 159 - ((x3d << 10) / z3d);
- y2d = 99 + ((y3d << 10) / z3d);
- }
-
-
- /*
- if (z3d > 32767)
- {
- x2d = x3d * perspect[32767];
- x2d = 159 + (x2d >> 6);
-
- y2d = y3d * perspect[32767];
- y2d = 99 - (y2d >> 6);
- }
- else
- {
- x2d = x3d * perspect[z3d];
- x2d = 159 + (x2d >> 6);
-
- y2d = y3d * perspect[z3d];
- y2d = 99 - (y2d >> 6);
- }
- */
- }
-
- void point3d::display(int color)
- {
- setPixel((int) x2d, (int) y2d, color);
- }
-
- // set new origin coordinates
-
- void point3d::setNewOrigin(point3d *p)
- {
- oX = p->x3d;
- oY = p->y3d;
- oZ = p->z3d;
-
- localX = x3d - oX;
- localY = y3d - oY;
- localZ = z3d - oZ;
-
- rotoX = localX;
- rotoY = localY;
- rotoZ = localZ;
-
- }
-
- // set new origin, retaining old local coordinates
-
- void point3d::globalXform2origin(point3d *p)
- {
- oX = p->x3d;
- oY = p->y3d;
- oZ = p->z3d;
-
- globalXform();
- xform2d();
- /*
- gRho = (long) sqrt(x3d * x3d + y3d * y3d + z3d * z3d);
- if (z3d == 0)
- gTheta = (long) 180 * atan(x3d) / PI;
- else
- gTheta = (long) 180 * atan(x3d / z3d) / PI;
-
- if (gRho == 0)
- gPhi = 0;
- else
- gPhi = (long) 180 * acos(y3d / gRho) / PI;
- */
- }
-
- // copy origin coordinates from another point
-
- void point3d::copyOrigin(point3d *p)
- {
- oX = p->oX;
- oY = p->oY;
- oZ = p->oZ;
-
- globalXform();
- xform2d();
- }
-
- /*
- void point3d::localRotate(int dTheta, int dPhi)
- {
-
- lTheta += dTheta;
- lPhi += dPhi;
-
- rotoX = (lRho * sin(lPhi * PI / 180) * cos(lTheta * PI / 180));
- rotoY = (lRho * cos(lPhi * PI / 180));
- rotoZ = (lRho * sin(lPhi * PI / 180) * sin(lTheta * PI / 180));
-
- globalXform();
-
- }
- */
-
- // rotate a point about its origin (slow method)
-
- void point3d::localRotate(int tX, int tY, int tZ)
- {
- int cosX, sinX, cosY, sinY, cosZ, sinZ;
-
- xDeg += tX;
- yDeg += tY;
- zDeg += tZ;
-
- cosX = zDCos(xDeg);
- sinX = zDSin(xDeg);
- cosY = zDCos(yDeg);
- sinY = zDSin(yDeg);
- cosZ = zDCos(zDeg);
- sinZ = zDSin(zDeg);
-
- // Z axis rotation first
- i = (long) ((localX * cosZ - localY * sinZ) >> SINSHIFT);
- j = (long) ((localX * sinZ + localY * cosZ) >> SINSHIFT);
- k = (long) localZ;
-
- // now X axis rotation
- rotoY = (long) ((j * cosX - k * sinX) >> SINSHIFT);
- rotoZ = (long) ((j * sinX + k * cosX) >> SINSHIFT);
- k = (long) rotoZ;
-
- // now Y axis
- rotoX = (long) ((k * sinY + i * cosY) >> SINSHIFT);
- rotoZ = (long) ((k * cosY - i * sinY) >> SINSHIFT);
-
- globalXform();
- }
-
- // rotate a point about its origin (faster method, *trig array
- // used to store sin/cos data that remains constant for all
- // points in a given object
-
- void point3d::localRotate(int *trig)
- {
- // Z axis rotation first
- i = ((localX * trig[5] - localY * trig[4]) >> SINSHIFT);
- j = ((localX * trig[4] + localY * trig[5]) >> SINSHIFT);
- k = localZ;
-
- // now X axis rotation
- rotoY = ((j * trig[1] - k * trig[0]) >> SINSHIFT);
- rotoZ = ((j * trig[0] + k * trig[1]) >> SINSHIFT);
- k = rotoZ;
-
- // now Y axis
- rotoX = ((k * trig[2] + i * trig[3]) >> SINSHIFT);
- rotoZ = ((k * trig[3] - i * trig[2]) >> SINSHIFT);
-
- globalXform();
-
- }
-
- // rotate a point about THE (0, 0, 0) origin
-
- void point3d::globalRotate(int *trig)
- {
- // Z axis rotation first
- i = (long) ((x3d * trig[5] - y3d * trig[4]) >> SINSHIFT);
- j = (long) ((x3d * trig[4] + y3d * trig[5]) >> SINSHIFT);
- k = (long) z3d;
-
- // now X axis rotation
- y3d = (long) ((j * trig[1] - k * trig[0]) >> SINSHIFT);
- z3d = (long) ((j * trig[0] + k * trig[1]) >> SINSHIFT);
- k = (long) z3d;
-
- // now Y axis
- x3d = (long) ((k * trig[2] + i * trig[3]) >> SINSHIFT);
- z3d = (long) ((k * trig[3] - i * trig[2]) >> SINSHIFT);
-
- }
-
- // translate (move) a point by (dX, dY, dZ)
-
- void point3d::translate(long dX, long dY, long dZ)
- {
- oX += dX;
- oY += dY;
- oZ += dZ;
-
- globalXform();
- }
-
- // transform local coordinates to global (world) coordinates
-
- void point3d::globalXform()
- {
- x3d = rotoX + oX;
- y3d = rotoY + oY;
- z3d = rotoZ + oZ;
- }
-
- // zero the normal for this point (used for gouraud shading)
-
- void point3d::zeroNormal()
- {
- nX = 0;
- nY = 0;
- nZ = 0;
- nCount = 0;
- }
-
- // add (dX, dY, dZ) to the normal for this point
-
- void point3d::addNormal(int dX, int dY, int dZ)
- {
- nX += dX;
- nY += dY;
- nZ += dZ;
- nCount ++;
- }
-
- // average the normal of this point
-
- void point3d::avgNormal()
- {
- long d;
-
- if (nCount)
- {
-
- nX /= nCount;
- nY /= nCount;
- nZ /= nCount;
-
- d = (long) sqrt(nX * nX + nY * nY + nZ * nZ);
-
- nX = (256 * nX) / d;
- nY = (256 * nY) / d;
- nZ = (256 * nZ) / d;
-
- }
-
- }
-
- void point3d::matRotate()
- {
- rotoX = (localX * matrix[0] + localY * matrix[1] + localZ * matrix[2]) >> SINSHIFT;
- rotoY = (localX * matrix[3] + localY * matrix[4] + localZ * matrix[5]) >> SINSHIFT;
- rotoZ = (localX * matrix[6] + localY * matrix[7] + localZ * matrix[8]) >> SINSHIFT;
-
- globalXform();
- }
-
- point3d::~point3d()
- {
- }
-
-
- //////
- //
- // line3d class definitions
- //
- //////
-
- // NOTE - I don't really know why I included the line3d object,
- // I never really use it anyway. Most of it is undoubtedly full
- // of bugs...
-
- line3d::line3d(point3d *p1, point3d *p2, int c)
- {
- point1 = p1;
- point2 = p2;
- calcVectors();
- color = c;
- flag = 0;
- }
-
- line3d::line3d(long x1, long y1, long z1, long x2, long y2, long z2, int c)
- {
- point1 = new point3d(x1, y1, z1);
- point2 = new point3d(x2, y2, z2);
- calcVectors();
- color = c;
- flag = 1;
- }
-
- void line3d::draw()
- {
- // draw_line(point1->x2d, point1->y2d, point2->x2d, point2->y2d, color);
- }
-
- void line3d::calcVectors()
- {
- i = (point1->x3d - point2->x3d);
- j = (point1->y3d - point2->y3d);
- k = (point1->z3d - point2->z3d);
- }
-
- long line3d::xOfT(double t)
- {
- return((long) (point1->x3d + (t * i)));
- }
-
- long line3d::yOfT(double t)
- {
- return((long) (point1->y3d + (t * j)));
- }
-
- long line3d::zOfT(double t)
- {
- return((long) (point1->z3d + (t * k)));
- }
-
- double line3d::tOfX(long x)
- {
- return((i == 0 ? 0 : (x - point1->x3d) / i));
- }
-
- double line3d::tOfY(long y)
- {
- return((j == 0 ? 0 : (y - point1->y3d) / j));
- }
-
- double line3d::tOfZ(long z)
- {
- return((k == 0 ? 0 : (z - point1->z3d) / k));
- }
-
- void line3d::localRotate(double tX, double tY, double tZ)
- {
- point1->localRotate(tX, tY, tZ);
- point2->localRotate(tX, tY, tZ);
- calcVectors();
- }
-
- line3d::~line3d()
- {
- if (flag)
- {
- delete point1;
- delete point2;
- }
- }
-
-
- //////
- //
- // polygon class definitions
- //
- //////
-
- // These are all triangles BTW
-
- polygon::polygon()
- {
- }
-
- polygon::polygon(point3d *v1, point3d *v2, point3d *v3, int c)
- {
- setColor(c);
- normal = new point3d;
- setTo(v1, v2, v3);
- shading = sNone;
- facing = fBoth;
- }
-
- polygon::polygon(point3d *v1, point3d *v2, point3d *v3, point3d *norm, int c)
- {
- setColor(c);
-
- p1 = v1;
- p2 = v2;
- p3 = v3;
-
- normal = norm;
-
- line = new line3d* [3];
- line[0] = new line3d(p1, p2, color);
- line[1] = new line3d(p2, p3, color);
- line[2] = new line3d(p3, p1, color);
-
- }
-
- void polygon::setTo(point3d *v1, point3d *v2, point3d *v3)
- {
- float i, j, k, d;
-
- p1 = v1;
- p2 = v2;
- p3 = v3;
-
- i = (float) (((p2->localY - p1->localY) * (p3->localZ - p1->localZ)) -
- ((p2->localZ - p1->localZ) * (p3->localY - p1->localY)));
-
- j = (float) (((p2->localZ - p1->localZ) * (p3->localX - p1->localX)) -
- ((p2->localX - p1->localX) * (p3->localZ - p1->localZ)));
-
- k = (float) (((p2->localX - p1->localX) * (p3->localY - p1->localY)) -
- ((p2->localY - p1->localY) * (p3->localX - p1->localX)));
-
- d = (float) sqrt((double) ((i * i) + (j * j) + (k * k)));
-
- i = (float) (i / d * 256);
- j = (float) (j / d * 256);
- k = (float) (k / d * 256);
-
- normal->setTo((long) i, (long) j, (long) k);
- normal->copyOrigin(p1);
-
- line = new line3d* [3];
- line[0] = new line3d(p1, p2, color);
- line[1] = new line3d(p2, p3, color);
- line[2] = new line3d(p3, p1, color);
-
- }
-
- // average Z value of a polygon, used for depth sorting
-
- long polygon::avgZ()
- {
- return((long) ((p1->z3d + p2->z3d + p3->z3d) / 3));
- }
-
- void polygon::setColor(int c)
- {
- color = c;
- }
-
- void polygon::wireFrame()
- {
- for (count = 0; count < 3; count++)
- line[count]->draw();
- }
-
- void polygon::paintSolid()
- {
- //dot = dotProduct(normal, camera.view);
- //if (dot < 0)
- if (shading)
- dot = -(dotProduct(normal, camera.light));
-
- poly3(p1->x2d, p1->y2d, p2->x2d, p2->y2d, p3->x2d, p3->y2d,
- color + (dot >> 4));
-
- // NOTE: dot >> 4 = (dot / 256 * 16) = cos T * 16 = offset into
- // block of 16 colors
-
- }
-
- void polygon::setNewOrigin(point3d *p)
- {
- p1->setNewOrigin(p);
- p2->setNewOrigin(p);
- p3->setNewOrigin(p);
- normal->setNewOrigin(p);
- }
-
- // this function should be called for all polygons in an object,
- // following which point->avgNormals() should be called for all
- // points in an object. The obj3d->setGNormals function takes
- // care of all of this...
-
- void polygon::setGNormals()
- {
- p1->addNormal(normal->rotoX, normal->rotoY, normal->rotoZ);
- p2->addNormal(normal->rotoX, normal->rotoY, normal->rotoZ);
- p3->addNormal(normal->rotoX, normal->rotoY, normal->rotoZ);
- }
-
- void polygon::gShade()
- {
- //int dot1, dot2, dot3;
-
- //dot = dotProduct(normal, camera.view);
- //if (dot < 0)
- //{
- dot1 = abs(dotProduct((point3d *) p1->normal, camera.light));
- dot2 = abs(dotProduct((point3d *) p2->normal, camera.light));
- dot3 = abs(dotProduct((point3d *) p3->normal, camera.light));
-
- gzpoly3(p1->x2d, p1->y2d, p1->z3d, color + (dot1 >> 4),
- p2->x2d, p2->y2d, p2->z3d, color + (dot2 >> 4),
- p3->x2d, p3->y2d, p3->z3d, color + (dot3 >> 4));
- //}
- }
-
- void polygon::setShading(int shade)
- {
- shading = shade;
- }
-
- void polygon::setFacing(int face)
- {
- facing = face;
- }
-
- // display a polygon according to the set shading and facing data
-
- void polygon::display()
- {
- if (shading)
- {
- if (facing)
- {
- dot = normal->rotoZ;
- if (facing == fInside)
- dot = -dot;
-
- if (dot < 0)
- {
- if (shading == sGouraud)
- gShade();
- else
- zbFlat();
- }
-
- }
- else
- {
- if (shading == sGouraud)
- gShade();
- else
- paintSolid();
- }
- }
- else
- {
- if (facing)
- {
- dot = normal->rotoZ;
- if (facing == fInside)
- dot = -dot;
-
- if (dot < 0)
- {
- dot = 0;
- zbFlat();
- }
- }
- else
- {
- dot = 0;
- zbFlat();
- }
- }
-
- }
-
- void polygon::zbFlat()
- {
- //dot = dotProduct(normal, camera.view);
- //if (dot < 0)
- if (shading)
- dot = -(dotProduct(normal, camera.light));
-
- zpoly3(p1->x2d, p1->y2d, p1->z3d, p2->x2d, p2->y2d, p2->z3d,
- p3->x2d, p3->y2d, p3->z3d, color + (dot >> 4));
-
- // NOTE: dot >> 11 = (dot / 256 * 16) = cos T * 16 = offset into
- // block of 16 colors
-
- }
-
- polygon::~polygon()
- {
- for (count = 0; count < 3; count++)
- delete line[count];
- delete line;
- delete normal;
- }
-
-
- //////
- //
- // obj3d class definitions
- //
- //////
-
-
- obj3d::obj3d(long x, long y, long z)
- {
- origin = new point3d(x, y, z);
-
- numPoints = 0;
- numNormals = 0;
- numPolys = 0;
-
- point = new point3d* [1];
- normal = new point3d* [1];
- poly = new polygon* [1];
-
- trig = new int [6];
-
- xDeg = 0;
- yDeg = 0;
- zDeg = 0;
-
- }
-
- // the save and load functions are out of date. If you wish, you may
- // rewrite them...
-
- void obj3d::save(FILE *fp)
- {
- int numWritten, count2;
-
- polyRec *pRec = new polyRec;
- objFileHeader *header = new objFileHeader;
-
- // assumes fp has already been opened, so we can store multiple objects
- // in the same file
-
- header->numPoints = numPoints;
- header->numPolys = numPolys;
-
- numWritten = fwrite(header, sizeof(objFileHeader), 1, fp);
-
- for (count = 0; count < numPoints; count++)
- point[count]->save(fp);
-
- for (count2 = 0; count2 < numPolys; count2++)
- {
- pRec->p1 = getPointNum(poly[count2]->p1);
- pRec->p2 = getPointNum(poly[count2]->p2);
- pRec->p3 = getPointNum(poly[count2]->p3);
- pRec->normal = getPointNum(poly[count2]->normal);
- pRec->color = poly[count2]->color;
-
- numWritten = fwrite(pRec, sizeof(polyRec), 1, fp);
-
- }
-
- }
-
- void obj3d::load(FILE *fp)
- {
- int numRead;
-
- polyRec *pRec = new polyRec;
- objFileHeader *header = new objFileHeader;
-
- // free old data
-
- for (count = 0; count < numPoints; count++)
- delete point[count];
-
- for (count = 0; count < numPolys; count++)
- delete point[count];
-
- // assumes fp has already been opened, so we can store multiple objects
- // in the same file
-
- numRead = fread(header, sizeof(objFileHeader), 1, fp);
-
- numPoints = header->numPoints;
- numPolys = header->numPolys;
-
- for (count = 0; count < numPoints; count++)
- {
- point[count] = new point3d;
- point[count]->load(fp);
- point[count]->globalXform2origin(origin);
- }
-
- for (count = 0; count < numPolys; count++)
- {
- numRead = fread(pRec, sizeof(polyRec), 1, fp);
-
- poly[count] = new polygon(point[pRec->p1], point[pRec->p2],
- point[pRec->p3], point[pRec->normal], pRec->color);
- }
-
- // nix the old rotations...
-
- xDeg = 0;
- yDeg = 0;
- zDeg = 0;
- }
-
- // add a point whose coordinates are given as local to the origin of
- // this object to this objects list of points
-
- void obj3d::addLocalPoint(long x, long y, long z)
- {
- point3d **temp;
-
- temp = new point3d* [numPoints + 1];
- memcpy(temp, point, numPoints * sizeof(point3d*));
-
- delete point;
- point = temp;
-
- numPoints++;
- point[numPoints - 1] = new point3d(x, y, z);
- point[numPoints - 1]->globalXform2origin(origin);
-
- }
-
- void obj3d::addNormal(long x, long y, long z)
- {
- point3d **temp;
-
- temp = new point3d* [numNormals + 1];
- memcpy(temp, normal, numNormals * sizeof(point3d*));
-
- delete normal;
- normal = temp;
-
- numNormals++;
- normal[numNormals - 1] = new point3d(x, y, z);
- normal[numNormals - 1]->globalXform2origin(origin);
-
- }
-
- void obj3d::addLocalPoint(point3d *p)
- {
- point3d **temp;
-
- temp = new point3d* [numPoints + 1];
- memcpy(temp, point, numPoints * sizeof(point3d*));
-
- delete point;
- point = temp;
-
- p->globalXform2origin(origin);
- numPoints++;
- point[numPoints - 1] = p;
- }
-
- void obj3d::addNormal(point3d *p)
- {
- point3d **temp;
-
- temp = new point3d* [numNormals + 1];
- memcpy(temp, normal, numNormals * sizeof(point3d*));
-
- delete normal;
- normal = temp;
-
- p->globalXform2origin(origin);
- numNormals++;
- normal[numNormals - 1] = p;
- }
-
- // add a point whose coordinates are given in terms of THE (0,0,0)
- // origin to this object's list of points
-
- void obj3d::addGlobalPoint(long x, long y, long z)
- {
- addLocalPoint(x - origin->x3d, y - origin->y3d, z - origin->z3d);
- }
-
- void obj3d::addGlobalPoint(point3d *p)
- {
- p->setNewOrigin(origin);
- addLocalPoint(p);
- }
-
- // add a local polygon (whose vertices are local points)
-
- void obj3d::addLocalPoly(polygon *pg)
- {
- polygon **temp;
-
- temp = new polygon* [numPolys + 1];
- memcpy(temp, poly, numPolys * sizeof(polygon*));
-
- delete poly;
- poly = temp;
-
- numPolys++;
- poly[numPolys - 1] = pg;
- addNormal(pg->normal);
- }
-
- void obj3d::addLocalPoly(int p1, int p2, int p3, int c)
- {
- polygon *pg = new polygon(point[p1], point[p2], point[p3], c);
- addLocalPoly(pg);
- }
-
- // add a poly whose vertices are given in global coordinates
-
- void obj3d::addGlobalPoly(polygon *pg)
- {
- pg->setNewOrigin(origin);
- addLocalPoly(pg);
- }
-
- int obj3d::getPointNum(long x, long y, long z)
- {
- for (count = 0; count < numPoints; count++)
- if (point[count]->localX == x && point[count]->localY == y &&
- point[count]->localZ == z)
- return(count);
-
- // couldn't find it, let's CREATE IT!
- addLocalPoint(x, y, z);
- return(numPoints - 1);
- }
-
- int obj3d::getPointNum(point3d *p)
- {
- for (count = 0; count < numPoints; count++)
- if (point[count] == p)
- return(count);
-
- return(-1);
- }
-
- // rotate this object about it's origin
-
- void obj3d::localRotate(int tX, int tY, int tZ)
- {
- xDeg += tX;
- yDeg += tY;
- zDeg += tZ;
-
- xDeg %= 360;
- yDeg %= 360;
- zDeg %= 360;
-
- trig[0] = zDSin(xDeg);
- trig[1] = zDCos(xDeg);
- trig[2] = zDSin(yDeg);
- trig[3] = zDCos(yDeg);
- trig[4] = zDSin(zDeg);
- trig[5] = zDCos(zDeg);
-
- for (count = 0; count < numPoints; count++)
- {
- point[count]->localRotate(trig);
- point[count]->xform2d();
- }
-
- for (count = 0; count < numNormals; count++)
- normal[count]->localRotate(trig);
- }
-
- void obj3d::matRotate(int tX, int tY, int tZ)
- {
- int cx, cy, cz, sx, sy, sz;
-
- // 0 1 2
- // 3 4 5
- // 6 7 8
-
- xDeg += tX;
- yDeg += tY;
- zDeg += tZ;
-
- xDeg %= 360;
- yDeg %= 360;
- zDeg %= 360;
-
- //cx = cos((double) xDeg * PI / 180);
- //sx = sin((double) xDeg * PI / 180);
- //cy = cos((double) yDeg * PI / 180);
- //sy = sin((double) yDeg * PI / 180);
- //cz = cos((double) zDeg * PI / 180);
- //sz = sin((double) zDeg * PI / 180);
-
- sx = zDSin(xDeg);
- cx = zDCos(xDeg);
- sy = zDSin(yDeg);
- cy = zDCos(yDeg);
- sz = zDSin(zDeg);
- cz = zDCos(zDeg);
-
- matrix[0] = ((cz * cy) << SINSHIFT ) + (((sx * sz) ) * sy) ;
- matrix[1] = ((-sz * cy) << SINSHIFT ) + (((sx * cz) ) * sy) ;
- matrix[2] = (cx * sy) << SINSHIFT;
- matrix[3] = (cx * sz) << SINSHIFT;
- matrix[4] = (cx * cz) << SINSHIFT;
- matrix[5] = -sx << (2 * SINSHIFT);
- matrix[6] = ((-cz * sy) << SINSHIFT) + (((sx * sz) ) * cy) ;
- matrix[7] = ((sz * sy) << SINSHIFT) + (((sx * cz) ) * cy) ;
- matrix[8] = (cx * cy) << SINSHIFT;
-
- matrix[0] >>= 16;
- matrix[1] >>= 16;
- matrix[2] >>= 16;
- matrix[3] >>= 16;
- matrix[4] >>= 16;
- matrix[5] >>= 16;
- matrix[6] >>= 16;
- matrix[7] >>= 16;
- matrix[8] >>= 16;
-
- for (count = 0; count < numPoints; count++)
- {
- point[count]->matRotate();
- point[count]->xform2d();
- }
-
- for (count = 0; count < numNormals; count++)
- normal[count]->matRotate();
- }
-
-
- /*
- void obj3d::localRotate(int dTheta, int dPhi)
- {
- for (count = 0; count < numPoints; count++)
- point[count]->localRotate(dTheta, dPhi);
- }
- */
-
- // translate (move) this object
-
- void obj3d::translate(int dX, int dY, int dZ)
- {
- origin->translate(dX, dY, dZ);
- for (count = 0; count < numPoints; count++)
- {
- point[count]->translate(dX, dY, dZ);
- point[count]->xform2d();
- }
-
- for (count = 0; count < numNormals; count++)
- normal[count]->translate(dX, dY, dZ);
- }
-
- // rotate this object about THE (0,0,0) origin
-
- void obj3d::globalRotate(int *trig)
- {
- origin->globalRotate(trig);
- for (count = 0; count < numPoints; count++)
- {
- point[count]->globalRotate(trig);
- point[count]->xform2d();
- }
-
- for (count = 0; count < numNormals; count++)
- normal[count]->globalRotate(trig);
- }
-
- // depth sort this object's planes
-
- void obj3d::sortPlanes()
- {
- polygon *temp;
- register int pos, index;
-
- for (pos = 0; pos < (numPolys - 1); pos++)
- {
- index = pos;
- for (count = index + 1; count < numPolys; count++)
- if (poly[count]->avgZ() > poly[index]->avgZ())
- index = count;
-
- if (index != pos)
- {
- temp = poly[pos];
- poly[pos] = poly[index];
- poly[index] = temp;
- }
- }
-
- }
-
- // display as dots
-
- void obj3d::paintDots()
- {
- for (count = 0; count < numPoints; count++)
- point[count]->display(15);
- }
-
- // display as a wireframe
-
- void obj3d::wireFrame()
- {
- sortPlanes();
- for (count = 0; count < numPolys; count++)
- poly[count]->wireFrame();
- }
-
- // display Lambert (flat) shaded
-
- void obj3d::paintSolid()
- {
- sortPlanes();
- for (count = 0; count < numPolys; count++)
- poly[count]->paintSolid();
- }
-
- // set the location of this object in global coordinates
-
- void obj3d::setLocation(long x, long y, long z)
- {
- origin->setTo(x, y, z);
- for (count = 0; count < numPoints; count++)
- point[count]->setNewOrigin(origin);
- }
-
- // have this object set up its normal vectors needed for gouraud shading
-
- void obj3d::setGNormals()
- {
- int temp;
-
- for (count = 0; count < numPolys; count++)
- poly[count]->setGNormals();
-
- for (count = 0; count < numPoints; count++)
- point[count]->avgNormal();
-
- temp = numPoints;
- for (count = 0; count < temp; count++)
- if (point[count]->nCount)
- {
- addNormal(point[count]->nX, point[count]->nY, point[count]->nZ);
- point[count]->normal = (void *) normal[numNormals - 1];
- }
-
- }
-
- // gouraud shade this object
-
- void obj3d::gShade()
- {
- sortPlanes();
- for (count = 0; count < numPolys; count++)
- poly[count]->gShade();
-
- }
-
- // universal display function that utilizes each polygon's shading
- // and facing data. This allows you to combine gouraud, flat, and
- // nonshaded polygons in the same object.
-
- void obj3d::display()
- {
- //sortPlanes();
- for (count = 0; count < numPolys; count++)
- poly[count]->display();
- }
-
- void obj3d::zbFlat()
- {
- for (count = 0; count < numPolys; count++)
- poly[count]->display();
- }
-
- obj3d::~obj3d()
- {
- for (count = 0; count < numPolys; count++)
- delete poly[count];
-
- for (count = 0; count < numNormals; count++)
- delete normal[count];
-
- for (count = 0; count < numPoints; count++)
- delete point[count];
-
- delete trig;
- delete poly;
- delete point;
- delete origin;
- }
-
-
- // THE WORLD AND VIEWPOINT CLASSES HAVE NOT BEEN FULLY IMPLEMENTED! If
- // you want to use them, rewrite them. You MUST leave the light and view
- // vectors in the camera class, though. They are used for shading and
- // plane elimination
-
- //////
- //
- // world3d class definitons
- //
- //////
-
-
- world3d::world3d()
- {
- object = new obj3d* [MAX_OBJS];
- numObjs = 0;
- initSinCos();
- initPerspect();
- }
-
- world3d::~world3d()
- {
- int count;
-
- delPerspect();
- for (count = 0; count < numObjs; count++)
- delete object[count];
-
- delete object;
- }
-
-
- //////
- //
- // viewPoint class definitions
- //
- //////
-
-
- viewPoint::viewPoint()
- {
- location = new point3d(0, 0, 0);
- light = new point3d(0, 0, 1);
- view = new point3d(0, 0, 1);
- }
-
- viewPoint::~viewPoint()
- {
- delete location;
- delete light;
- delete view;
- }
-
-